package com.anabur.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;



public abstract class AafAbstractDAO {
	
	protected SessionFactory sessionFac;
	
	public AafAbstractDAO(SessionFactory sessionFac){
		this.sessionFac=sessionFac;
	}
	
	public boolean insertOrModify(AafAbstractPersistent pojo) throws Exception{
		Session sess = null;
		Transaction tx = null;
		try{
			sess=sessionFac.openSession();
			tx=sess.beginTransaction();
			sess.saveOrUpdate(pojo);
			sess.flush();
			tx.commit();
			sess.close();
		}catch (Exception e) {
			tx.rollback();
			sess.close();
			return false;
		}
		return true;
	}

	public void delete(AafAbstractPersistent pojo) throws Exception{
		Session sess = null;
		Transaction tx = null;
		try{
			sess=sessionFac.openSession();
			tx=sess.beginTransaction();
			sess.delete(pojo);
			sess.flush();
			tx.commit();
			sess.close();
		}catch (Exception e) {
			tx.rollback();
			sess.close();
		}	
	}
	
	protected List<HashMap<String, Object>> getQueryHQL(String nameQuery) {
		Session session = sessionFac.openSession();
		Query query = session.getNamedQuery(nameQuery);
		ScrollableResults sr = query.scroll();
		String[] columnNames = query.getReturnAliases();
		
		List<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
		HashMap<String, Object> row;
		boolean containRows = false; 
        while (sr.next()) {
        	containRows = true;
            row = new LinkedHashMap <String, Object>();
            Object[] rowValues = sr.get();
            for (int i = 0; i < columnNames.length; i++) {
            	if(!columnNames[i].equals("ID")){
            		row.put(nameQuery + "." +columnNames[i],rowValues[i]);
            	} else {
            		row.put(columnNames[i],rowValues[i]);
            	}
            }
            result.add(row);
        }
        if(!containRows){
        	row = new LinkedHashMap<String, Object>();
			for (int i = 0; i < columnNames.length; i++) {
				if(!columnNames[i].equals("ID")){
            		row.put(nameQuery + "." +columnNames[i],null);
            	} else {
            		row.put(columnNames[i],null);
            	}
            }
			result.add(row);
		}
        session.close();
		return result;
	}
	
	public AafAbstractPersistent findPersistentByID(Long id) {
		AafAbstractPersistent abstractPojo=null;
		Session sess = null;
		try{
			sess = sessionFac.openSession();
			Query query = sess.createQuery("from " + getNameOfPojo() + " where id = :ID");
			query.setLong("ID",id);
			abstractPojo = (AafAbstractPersistent) query.uniqueResult();
			sess.close();
		}catch (Exception e) {
			sess.close();
		}		
		return abstractPojo;
	}
	
	protected abstract String getNameOfPojo();
	
	public List<HashMap<String, Object>> findDataForABM() {
		return getQueryHQL(getNameOfPojo() + ".data_for_abm");
	}
}
